package com.qf.test;

import com.qf.DongProxy.FangDongService;
import com.qf.DongProxy.impl.FangDongServiceImpl;
import com.qf.staticProxy.Fd;
import com.qf.staticProxy.Fd2;
import com.qf.staticProxy.Zj1;
import com.qf.staticProxy.ZuKe;
import org.junit.Test;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/*
 *@Description:
 *@author:刘哥
 *@Date:86180 2022/8/25 16:21
 */
public class Demo {
    @Test
    public  void test01(){
        Fd fd=new Fd();
        Zj1 zj1=new Zj1();
        ZuKe zuKe=new ZuKe();
        zuKe.setChuZu(zj1);
        zj1.setChuZu(fd);
        zuKe.zfz();
        Fd2 fd2=new Fd2();
        zj1.setChuZu(fd2);
        zuKe.zfz();

    }
    @Test
    public  void test02(){
        FangDongService fangDongService=new FangDongServiceImpl();

//        创建代理对象
        /**
         *
         * fangDongService.getClass().getClassLoader()：代表与目标对象相同的类加载器目标对象.getClass().getClassLoader()
         *  fangDongService.getClass().getInterfaces()：代表代理对象的类型，实现的是那个接口
         * new InvocationHandler() ：具体的代理对象实现的操作，InvocationHandler接口
         *
         * getClassLoader():类加载器，寻找需要代理的类相同的类
         * getInterfaces:获得当前对象实现的所有接口，可以通过索引取
         * InvocationHandler：创建的代理对象实现什么方法
         */
        FangDongService fangDongService1 = (FangDongService) Proxy.newProxyInstance(fangDongService.getClass().getClassLoader(),fangDongService.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //result: 原始方法的返回值   如果原始类型方法返回值void  null
                System.out.println("开启事务");
                Object result = method.invoke(fangDongService, args);
                System.out.println("提交事务");
                return result;
            }
        });
        fangDongService1.zuFang();
    }

    /**
     * JDK动态代理模式(通过实现同一个接口实现)
     */
    @Test
    public  void test03(){
        FangDongService fangDongService=new FangDongServiceImpl();
        System.out.println(fangDongService.getClass().getInterfaces()[0]);

        System.out.println( FangDongServiceImpl.class.getClassLoader());
    }

    /**
     * CGLIB动态代理模式(通过继承实现,代理对象继承真实对象)
     */
    @Test
    public  void test04(){
//        创建真实对象
        FangDongService fangDongService=new FangDongServiceImpl();
//        创建动态代理对象
        Enhancer enhancer = new Enhancer();
//        设置父类对象
        enhancer.setSuperclass(fangDongService.getClass());
//        设置回调函数(调用的方法)
        enhancer.setCallback(new org.springframework.cglib.proxy.InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                System.out.println("发布租房公告");
                Object invoke = method.invoke(fangDongService, objects);
                System.out.println("租房成功");
                return invoke;
            }
        });
//        创建动态代理类
        FangDongService proxy = (FangDongService) enhancer.create();
        proxy.zuFang();
    }
}
